package com.vilen.learn.java7.V4;

/**
 * Created by vilen on 2017/9/24.
 * 不可变对象
 * 构建器模式可以解决这个问题。它由两部分组成：一个是实现了构建器泛型接口的内部静态类，
 * 另一个是构建不可变类实例的私有构造方法。
 *
 * 有了这段代码，你就可以创建新的Update对象：
    Update.Builder ub = new Update.Builder();
    Update u = ub.author(myAuthor).updateText("Hello").build();
 */
public class Update implements Comparable<Update> {
    //必须在构造方法中初始化final域
    private final Author author;
    private final String updateText;
    private final long createTime;

    public Author getAuthor() {
        return author;
    }

    public String getUpdateText() {
        return updateText;
    }

    private Update(Builder b_) {
        author = b_.author;
        updateText = b_.updateText;
        createTime = b_.createTime;
    }

    @Override
    public int compareTo(Update other_) {
        if (null == other_) {
            throw new NullPointerException();
        }
        return (int) (other_.createTime - this.createTime);
    }

    //构造器类必须是静态内部类
    public static class Builder implements ObjBuilder<Update>{

        public long createTime;
        private Author author;
        private String updateText;
        // 可用在调用链中返回Builder的方法
        public Builder author(Author author_) {
            author = author_;
            return this;
        }

        public Builder updateText(String updateText_) {
            updateText = updateText_;
            return this;
        }

        public Builder createTime(long createTime_) {
            createTime = createTime_;
            return this;
        }

        @Override
        public Update build() {
            return new Update(this);
        }
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((author == null) ? 0 : author.hashCode());
        result = prime * result + (int) (createTime ^ (createTime >>> 32));
        result = prime * result
                + ((updateText == null) ? 0 : updateText.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Update other = (Update) obj;
        if (author == null) {
            if (other.author != null)
                return false;
        } else if (!author.equals(other.author))
            return false;
        if (createTime != other.createTime)
            return false;
        if (updateText == null) {
            if (other.updateText != null)
                return false;
        } else if (!updateText.equals(other.updateText))
            return false;
        return true;
    }

    @Override
    public String toString() {
        return "Update [author=" + author + ", updateText=" + updateText
                + ", createTime=" + createTime + "]";
    }
}
